
#include "semaphore.h"

#define SEM_FILE "./semfile"
extern semid;

 union semun {
	 int              val;    
	 struct semid_ds *buf;    
	 unsigned short  *array;  /* 不做要求 */
	 struct seminfo  *__buf;  /* 不做要求 */
};

void print_err(char *estr){
	perror(estr);
	exit(-1);
}


int creat_or_get_sem(int nsems){
	int semid;
	int fd =-1;
	key_t key =-1;

	fd =open(SEM_FILE,O_RDWR|O_CREAT,0664);
	if(fd ==-1) print_err("open fail");

	key =ftok(SEM_FILE,'a');
	if(key ==-1) print_err("ftok err");
	semid =semget(key,nsems,0644|IPC_CREAT);
	if(semid == -1) print_err("semget err");
	return semid;
}

void init_sem(int semid,int semnum,int val){
	int ret =-1;
	union semun sem_un;

	sem_un.val = val;
	ret= semctl(semid,semnum,SETVAL,sem_un.val);
	if(ret == -1) print_err("semctl err");
}
void del_sem(int semid){
	int ret =-1;
	ret= semctl(semid,0,IPC_RMID);
	if(ret == -1) print_err("semctl del err");
	remove(SEM_FILE);
	
}
void signal_fun(int signo){
	del_sem(semid);
	exit(-1);
}

void sem_p(int semid,int semnunm_buf[],int nsops){
	int ret =-1;
	int i =0;
	struct sembuf sops[nsops];

	for(;i<nsops;i++){
		sops[i].sem_num=semnunm_buf[i];
		sops[i].sem_op=-1;
		sops[i].sem_flg=SEM_UNDO;
	}
	
	ret=semop(semid,sops,nsops);
	if(ret == -1) print_err("semop p err");
}
void sem_v(int semid,int semnunm_buf[],int nsops){
	int ret =-1;
	int i =0;
	struct sembuf sops[nsops];

	for(;i<nsops;i++){
		sops[i].sem_num=semnunm_buf[i];
		sops[i].sem_op=1;
		sops[i].sem_flg=SEM_UNDO;
	}
	
	ret=semop(semid,sops,nsops);
	if(ret == -1) print_err("semop v err");
}